<?php

class Backend_ShippingController extends RCMS_Core_BaseController {

    private $_shoppingConfig;

    public function init() {
        parent::init();
        $this->_model = new Backend_ShoppingModel();
        $this->_checkLogin(array('calculate','setuserselectedshipper'));
        $this->_shoppingConfig = $this->_model->selectShoppingConfig();
    }

    /**
     * Scan services dir and returns array of available shippers.
     */
    private function _getserviceslist() {
        $this->_helper->getHelper('layout')->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);

        //$services = array ('internal');
        $services = array ();
        $servicePath = APPLICATION_PATH . '/app/objects/Shipping/Services/';
        $list = RCMS_Tools_FilesystemTools::scanDir($servicePath);
        foreach ($list as $value) {
            $name = str_replace('.php','',$value);
            $classname = 'RCMS_Object_Shipping_Services_'.$name;
            if (class_exists($classname)
                    && in_array('RCMS_Core_ShippingServiceInterface',class_implements($classname))){
                array_push($services, $name);
            }
        }
        
        return $services;
        
    }
    /**
     * Calculates shipping price using choosen shipper module. (AJAX)
     * @return void
     */
    public function calculateAction() {
        $this->_helper->getHelper('layout')->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);

        if ($this->getRequest()->isPost()){
            $serviceName = $this->getRequest()->getParam('shippingService');
            $companyAddress = array(
                'address1'  => $this->_shoppingConfig['address'],
                'address2'  => $this->_shoppingConfig['address2'],
                'city'      => $this->_shoppingConfig['city'],
                'state'     => $this->_shoppingConfig['state'],
                'zip'       => $this->_shoppingConfig['zip'],
                'country'   => $this->_shoppingConfig['country'],
                'phone'     => $this->_shoppingConfig['phone']
            );
            $shipping = new RCMS_Object_Shipping_Shipping();
            $userAddress = array(
                'firstname' => $this->getRequest()->getParam('firstname'),
                'lastname'  => $this->getRequest()->getParam('lastname'),
                'company'   => $this->getRequest()->getParam('company'),
                'email'     => $this->getRequest()->getParam('email'),
                'address1'  => $this->getRequest()->getParam('address1'),
                'address2'  => $this->getRequest()->getParam('address2'),
                'city'      => $this->getRequest()->getParam('city'),
                'state'     => $this->getRequest()->getParam('state'),
                'zip'       => $this->getRequest()->getParam('zip'),
                'country'   => $this->getRequest()->getParam('country'),
                'phone'     => $this->getRequest()->getParam('phone'),
                'mobile'    => $this->getRequest()->getParam('mobile'),
				'instructions' => strip_tags($this->getRequest()->getParam('instructions')),
				'referrer'  => $_SERVER['REMOTE_ADDR']
            );
            $shipping->setShippingAddress($userAddress);

            if ($serviceName == 'internal') {
                $this->countInternal();
                return;
            } else {
                $shipperPluginConf = unserialize($this->_shoppingConfig['shipping_plugin_conf']);
                $shipperGeneralConf = unserialize($this->_shoppingConfig['shipping_general']);
                $className = 'RCMS_Object_Shipping_Services_' . $shipperPluginConf['name'];
                $shoppingCart = new RCMS_Object_Shopping_ShoppingCart();
                if (class_exists($className)){
                    $service  = new $className($shipperPluginConf);
                    $service->setOrigination($companyAddress);
                    $service->setDestination($userAddress);
                    $service->setWeight($shoppingCart->getTotalWeight(), $shipperGeneralConf['weight-units']);
                    $result = $service->run();
                    if (count($result)>2 && is_array($result[0])){
                        echo json_encode($result);
                    } else {
                        $shipping->setShippingService( $result );
                        echo json_encode($result);
                    }
                }
            }

            
            
        }
    }

    /**
     * Internal calculation method
     * @return void
     */
    private function countInternal()
    {
        
            $shippingTotal = 0;
            $shoppingCart    = new RCMS_Object_Shopping_ShoppingCart();
            $shippingData    = new RCMS_Object_Shipping_Shipping();
            $shippingGeneral = unserialize($this->_shoppingConfig['shipping_general']);
            
            $userAddress = $shippingData->getShippingAddress();

            if ($userAddress['country'] == '') {
                
                echo json_encode(array('type' => 'error', 'price'=> 0));
                return;
            } else {
                $shippingType = ($userAddress['country'] == $this->_shoppingConfig['country'] ? 'national' : 'international');
            }

            switch ($this->_shoppingConfig['shipping_type']) {
                case 'pickup':
                    $shippingData->setShippingService(array ('type' => 'pickup', 'price'=> 0));
                    echo json_encode(array ('type' => 'pickup', 'price'=> 0));
                    return;
                    break;

                case 'amount':
                    $shippingAmount = unserialize($this->_shoppingConfig['shipping_amount']);
                    $amount = $shoppingCart->getTotalPrice();
                    
                    switch ($amount){
                        case ($amount < $shippingAmount[1]['limit']):
                            $shippingTotal = $shippingAmount[1][$shippingType];
                            break;

                        case ($amount < $shippingAmount[2]['limit']):
                            $shippingTotal = $shippingAmount[2][$shippingType];
                            break;

                        case ($amount > $shippingAmount[3]['limit']):
                            $shippingTotal = $shippingAmount[3][$shippingType];
                            if ($amount > $shippingGeneral['free-shipping-over']){
                                if ($shippingGeneral['free-shipping-options'] == $shippingType) {
                                    $shippingTotal = '0';
                                } else if ($shippingGeneral['free-shipping-options'] == 'both') {
                                    $shippingTotal = '0';
                                }
                            }
                            break;

                        default:
                            break;
                    }
                    break;

                case 'weight':
                    $shippingWeight = unserialize($this->_shoppingConfig['shipping_weight']);
                    $weight = $shoppingCart->getTotalWeight();

                    switch ($weight){
                        case ($weight < $shippingWeight[1]['limit']):
                            $shippingTotal = $shippingWeight[1][$shippingType];
                            break;
                        case ($weight < $shippingWeight[2]['limit']):
                            $shippingTotal = $shippingWeight[2][$shippingType];
                            break;
                        case ($weight > $shippingWeight[3]['limit']):
                            $shippingTotal = $shippingWeight[3][$shippingType];
                            break;
                    }
                    
                    break;
                default:
                    echo json_encode(array ('type' => 'error', 'price'=> 0));
                    return false;
                    break;
            }
		$shippingTotal = !$shippingTotal ? 0 : $shippingTotal;
        $shippingTotal = number_format($shippingTotal, 2, '.','');
        $shippingData->setShippingService(array('type' => 'internal '.$shippingType, 'price' => $shippingTotal));
        echo json_encode(array ('type' => 'internal '.$shippingType, 'price'=> $shippingTotal));
        return;

    }

	/**
	 * This function loads template where user can change config for shipping.
	 * @return <void>
	 */
	public function configAction()
    {
        $this->_helper->getHelper('layout')->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);
        $this->view->update = false;
        if ($this->getRequest()->isPost()) {
            /* save settings for shopping config */
            $shippingGeneral = $this->getRequest()->getParam('shipping-general');
            $shippingAmount  = $this->getRequest()->getParam('shipping-amount');
            $shippingWeight  = $this->getRequest()->getParam('shipping-weight');
            array_walk_recursive($shippingAmount,array($this,'_validateShippingData'));
            array_walk_recursive($shippingWeight,array($this,'_validateShippingData'));

            $data = array (
                'shipping_general'      =>  serialize($shippingGeneral),
                'shipping_amount'       =>  serialize($shippingAmount),
                'shipping_weight'       =>  serialize($shippingWeight),
                'shipping_type'         =>  trim(RCMS_Tools_Tools::stripSlashesIfQuotesOn($this->getRequest()->getParam('shipping-type'))),
            );
            $extShipperConf = $this->getRequest()->getParam('ext-shipper');
            if (isset($extShipperConf) && is_array($extShipperConf) && $extShipperConf['name']!='select') {
                $data['shipping_plugin_conf'] = serialize($extShipperConf);
            }
            unset($extShipperConf);
            if (count($this->_error) == 0){
                foreach ($data as $key => $value) {
                    $this->_model->updateShoppingConfig($key, $value);
                }
                $this->view->error = false;
                $this->view->update = true;
            } else {
                $this->view->error = true;
            }
        }
        if ($this->view->update == true){
            $this->_shoppingConfig = $this->_model->selectShoppingConfig();
        }
        $this->view->currency        = $this->_shoppingConfig['currency'];
        $this->view->shippingType    = $this->_shoppingConfig['shipping_type'];
        $this->view->shippingGeneral = unserialize($this->_shoppingConfig['shipping_general']);
        $this->view->shippingAmount  = unserialize($this->_shoppingConfig['shipping_amount']);
        $this->view->shippingWeight  = unserialize($this->_shoppingConfig['shipping_weight']);
        $this->view->extShippers     = $this->_getserviceslist();
        if (//$this->_shoppingConfig['shipping_type'] == 'external' &&
                isset($this->_shoppingConfig['shipping_plugin_conf']) && 
                $this->_shoppingConfig['shipping_plugin_conf'] != ''
                )
           {
                $shipperConfig = unserialize($this->_shoppingConfig['shipping_plugin_conf']);
                $shipperName =  $shipperConfig['name'];
                unset($shipperConfig['name']);
                $this->view->shippersConfForJS = json_encode($shipperConfig);
                $className = 'RCMS_Object_Shipping_Services_' . $shipperName;
                $shipper = new $className($shipperConfig);
                $this->view->extShipperName = $shipperName;
                $this->view->extShipperScreen = preg_replace('~name="([-_\w\s\d]+)([\[\]]{0,2})"~','name="ext-shipper[$1]$2"',$shipper->getConfigScreen());
        }
        //for translator
		echo $this->_translator->processScreen($this->view->render($this->getViewScript()));
	}

    /**
     *  internal function uses for validating shipping config data
     */
    private function _validateShippingData($item, $key) {
        if (!preg_match('/^(\d+(\.\d+)?)?$/', $item)) {
            array_push($this->_error,$key);
        }
    }

    /**
     * Return config screen (html) for choosed shipper (AJAX)
     */
    public function loadshipperconfigscreenAction(){
        $this->_helper->getHelper('layout')->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);
       
        if ($this->getRequest()->isPost()){
            $name = 'RCMS_Object_Shipping_Services_' . trim($this->getRequest()->getParam('name'));
            $config = unserialize($this->_shoppingConfig['shipping_plugin_conf']);
            $shipper = new $name($config);
            $return = array('html' => preg_replace('~name="([-_\w\s\d]+)([\[\]]{0,2})"~','name="ext-shipper[$1]$2"',$shipper->getConfigScreen()),
                'config' => $config);
            echo json_encode($return);
        }
    }

    public function setuserselectedshipperAction(){
        $this->_helper->getHelper('layout')->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);

        if ($this->getRequest()->isPost()) {
            $request = $this->getRequest()->getParams();
            unset($request['action']);
            unset($request['controller']);
            unset($request['module']);
            $shipperConf = unserialize($this->_shoppingConfig['shipping_plugin_conf']);
            $request['type'] = $this->_shoppingConfig['shipping_type'].'|'.$shipperConf['name'].'|'.$request['type'];
            $shipping = new RCMS_Object_Shipping_Shipping();
            $shipping->setShippingService($request);

            echo json_encode($request);
        }
    }
}
